home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / more.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  38KB  |  1,938 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18.  
  19. /*
  20. ** more.c - General purpose tty output filter and file perusal program
  21. **
  22. **    by Eric Shienbrood, UC Berkeley
  23. **
  24. **    modified by Geoff Peck, UCB to add underlining, single spacing
  25. **    modified by John Foderaro, UCB to add -c and MORE environment variable
  26. */
  27.  
  28. #include <sys/types.h>
  29. #include <sys/stat.h>
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <ctype.h>
  33. #include <signal.h>
  34. #include <sgtty.h>
  35. #include <setjmp.h>
  36. #include <stdio.h>
  37.  
  38. #undef SIGTSTP            /* POSIX requires it to be defined */
  39.  
  40. #ifndef _MINIX
  41. #include <sys/param.h>
  42. #include <sys/file.h>
  43. #endif
  44. #include <a.out.h>
  45.  
  46. /* varargs ------- */
  47. /*  varargs.h  */
  48.  
  49. typedef char *va_list;
  50.  
  51. #define  va_dcl        int va_alist;
  52. #define  va_start(p)    (p) = (va_list) &va_alist;
  53. #define  va_arg(p,type)    ( (type *) ((p)+=sizeof(type)) )[-1]
  54. #define  va_end(p)
  55.  
  56. #define  vfPrintf    _doPrintf
  57. #define  vPrintf(fmt,args)    vfPrintf(stdout,fmt,args)
  58. /* end of varargs.h -------- */
  59.  
  60. #ifdef _MINIX
  61. #include <limits.h>
  62. #endif /*  _MINIX */
  63.  
  64. #define HELPFILE    "/usr/lib/more.help"
  65. #define VI        "/usr/bin/vi"
  66.  
  67. #define Fopen(s,m)    (Currline = 0,file_pos=0,fopen(s,m))
  68. #define Ftell(f)    file_pos
  69. #define Fseek(f,off)    (file_pos=off,fseek(f,off,0))
  70. #define Getc(f)        (++file_pos, getc(f))
  71. #define Ungetc(c,f)    (--file_pos, ungetc(c,f))
  72.  
  73. #ifndef TIOCSETN
  74. #define TIOCSETN    TIOCSETP    /* Minix doesn't have SETN */
  75. #endif
  76. #ifndef TBDELAY
  77. #define TBDELAY        0006000        /* Minix doesn't have TBDELAY */
  78. #endif
  79.  
  80. #define MBIT    CBREAK
  81. #define stty(fd,argp)    ioctl(fd,TIOCSETN,argp)
  82.  
  83. #define TBUFSIZ    1024
  84. #define LINSIZ    256
  85. #define ctrl(letter)    (letter & 077)
  86. #define RUBOUT    '\177'
  87. #define ESC    '\033'
  88. #define QUIT    '\034'
  89.  
  90. int Printf();
  91.  
  92. struct sgttyb    otty, savetty;
  93. void        onquit(), end_it(), onsusp();
  94. long        file_pos, file_size;
  95. int        fnum, no_intty, no_tty, slow_tty;
  96. int        dum_opt, dlines, chgwinsz();
  97. int        nscroll = 11;    /* Number of lines scrolled by 'd' */
  98. int        fold_opt = 1;    /* Fold long lines */
  99. int        stop_opt = 1;    /* Stop after form feeds */
  100. int        ssp_opt = 0;    /* Suppress white space */
  101. int        ul_opt = 1;    /* Underline as best we can */
  102. int        promptlen;
  103. int        Currline;    /* Line we are currently at */
  104. int        startup = 1;
  105. int        firstf = 1;
  106. int        notell = 1;
  107. int        docrterase = 0;
  108. int        docrtkill = 0;
  109. int        bad_so;    /* True if overwriting does not turn off standout */
  110. int        inwait, Pause, errors;
  111. int        within;    /* true if we are within a file,
  112.             false if we are between files */
  113. int        hard, dumb, noscroll, hardtabs, clreol, eatnl;
  114. int        catch_susp;    /* We should catch the SIGTSTP signal */
  115. char        **fnames;    /* The list of file names */
  116. int        nfiles;        /* Number of files left to process */
  117. char        *shell;        /* The name of the shell to use */
  118. int        shellp;        /* A previous shell command exists */
  119. char        ch;
  120. jmp_buf        restore;
  121. char        Line[LINSIZ];    /* Line buffer */
  122. int        Lpp = 24;    /* lines per page */
  123. char        *Clear;        /* clear screen */
  124. char        *eraseln;    /* erase line */
  125. char        *Senter, *Sexit;/* enter and exit standout mode */
  126. char        *ULenter, *ULexit;    /* enter and exit underline mode */
  127. char        *chUL;        /* underline character */
  128. char        *chBS;        /* backspace character */
  129. char        *Home;        /* go to home */
  130. char        *cursorm;    /* cursor movement */
  131. char        cursorhome[40];    /* contains cursor movement to home */
  132. char        *EodClr;    /* clear rest of screen */
  133. char        *tgetstr();
  134. char        *tgoto();
  135. int        Mcol = 80;    /* number of columns */
  136. int        Wrap = 1;    /* set if automargins */
  137. int        soglitch;    /* terminal has standout mode glitch */
  138. int        ulglitch;    /* terminal has underline mode glitch */
  139. int        pstate = 0;    /* current UL state */
  140. char        *getenv();
  141. struct {
  142.     long chrctr, line;
  143. } context, screen_start;
  144.  
  145.  
  146.  
  147. main(argc, argv)
  148. int argc;
  149. char *argv[];
  150. {
  151.     register FILE    *f;
  152.     register char    *s;
  153.     register char    *p;
  154.     register char    ch;
  155.     register int    left;
  156.     int            prnames = 0;
  157.     int            initopt = 0;
  158.     int            srchopt = 0;
  159.     int            clearit = 0;
  160.     int            initline;
  161.     char        initbuf[80];
  162.     FILE        *checkf();
  163.  
  164.     nfiles = argc;
  165.     fnames = argv;
  166.     initterm ();
  167.     nscroll = Lpp/2 - 1;
  168.     if (nscroll <= 0)
  169.     nscroll = 1;
  170.     if(s = getenv("MORE")) argscan(s);
  171.     while (--nfiles > 0) {
  172.     if ((ch = (*++fnames)[0]) == '-') {
  173.         argscan(*fnames+1);
  174.     }
  175.     else if (ch == '+') {
  176.         s = *fnames;
  177.         if (*++s == '/') {
  178.         srchopt++;
  179.         for (++s, p = initbuf; p < initbuf + 79 && *s != '\0';)
  180.             *p++ = *s++;
  181.         *p = '\0';
  182.         }
  183.         else {
  184.         initopt++;
  185.         for (initline = 0; *s != '\0'; s++)
  186.             if (isdigit (*s))
  187.             initline = initline*10 + *s -'0';
  188.         --initline;
  189.         }
  190.     }
  191.     else break;
  192.     }
  193.     /* allow clreol only if Home and eraseln and EodClr strings are
  194.      *  defined, and in that case, make sure we are in noscroll mode
  195.      */
  196.     if(clreol)
  197.     {
  198.         if((Home == NULL) || (*Home == '\0') ||
  199.        (eraseln == NULL) || (*eraseln == '\0') ||
  200.            (EodClr == NULL) || (*EodClr == '\0') )
  201.           clreol = 0;
  202.     else noscroll = 1;
  203.     }
  204.     if (dlines == 0)
  205.     dlines = Lpp - (noscroll ? 1 : 2);
  206.     left = dlines;
  207.     if (nfiles > 1)
  208.     prnames++;
  209.     if (!no_intty && nfiles == 0) {
  210.     char *rindex();
  211.  
  212.     p = rindex(argv[0], '/');
  213.     fputs("Usage: ",stderr);
  214.     fputs(p ? p + 1 : argv[0],stderr);
  215.     fputs(" [-dfln] [+linenum | +/pattern] name1 name2 ...\n",stderr);
  216.     exit(1);
  217.     }
  218.     else
  219.     f = stdin;
  220.     if (!no_tty) {
  221.     signal(SIGQUIT, onquit);
  222.     signal(SIGINT, end_it);
  223. #ifdef SIGWINCH
  224.     signal(SIGWINCH, chgwinsz);
  225. #endif
  226. #ifdef SIGTSTP
  227.     if (signal (SIGTSTP, SIG_IGN) == SIG_DFL) {
  228.         signal(SIGTSTP, onsusp);
  229.         catch_susp++;
  230.     }
  231. #endif /*  SIGTSTP */
  232.     stty (fileno(stderr), &otty);
  233.     }
  234.     if (no_intty) {
  235.     if (no_tty)
  236.         copy_file (stdin);
  237.     else {
  238.         if ((ch = Getc (f)) == '\f')
  239.         doclear();
  240.         else {
  241.         Ungetc (ch, f);
  242.         if (noscroll && (ch != EOF)) {
  243.             if (clreol)
  244.             home ();
  245.             else
  246.             doclear ();
  247.         }
  248.         }
  249.         if (srchopt)
  250.         {
  251.         search (initbuf, stdin, 1);
  252.         if (noscroll)
  253.             left--;
  254.         }
  255.         else if (initopt)
  256.         skiplns (initline, stdin);
  257.         screen (stdin, left);
  258.     }
  259.     no_intty = 0;
  260.     prnames++;
  261.     firstf = 0;
  262.     }
  263.  
  264.     while (fnum < nfiles) {
  265.     if ((f = checkf (fnames[fnum], &clearit)) != NULL) {
  266.         context.line = context.chrctr = 0;
  267.         Currline = 0;
  268.         if (firstf) setjmp (restore);
  269.         if (firstf) {
  270.         firstf = 0;
  271.         if (srchopt)
  272.         {
  273.             search (initbuf, f, 1);
  274.             if (noscroll)
  275.             left--;
  276.         }
  277.         else if (initopt)
  278.             skiplns (initline, f);
  279.         }
  280.         else if (fnum < nfiles && !no_tty) {
  281.         setjmp (restore);
  282.         left = command (fnames[fnum], f);
  283.         }
  284.         if (left != 0) {
  285.         if ((noscroll || clearit) && (file_size != LONG_MAX))
  286.             if (clreol)
  287.             home ();
  288.             else
  289.             doclear ();
  290.         if (prnames) {
  291.             if (bad_so)
  292.             erase (0);
  293.             if (clreol)
  294.             cleareol ();
  295.             pr("::::::::::::::");
  296.             if (promptlen > 14)
  297.             erase (14);
  298.             Printf ("\n");
  299.             if(clreol) cleareol();
  300.             Printf("%s\n", fnames[fnum]);
  301.             if(clreol) cleareol();
  302.             Printf("::::::::::::::\n");
  303.             if (left > Lpp - 4)
  304.             left = Lpp - 4;
  305.         }
  306.         if (no_tty)
  307.             copy_file (f);
  308.         else {
  309.             within++;
  310.             screen(f, left);
  311.             within = 0;
  312.         }
  313.         }
  314.         setjmp (restore);
  315.         fflush(stdout);
  316.         fclose(f);
  317.         screen_start.line = screen_start.chrctr = 0L;
  318.         context.line = context.chrctr = 0L;
  319.     }
  320.     fnum++;
  321.     firstf = 0;
  322.     }
  323.     reset_tty ();
  324.     exit(0);
  325. }
  326.  
  327. argscan(s)
  328. char *s;
  329. {
  330.     int seen_num = 0;
  331.  
  332.     while (*s != '\0') {
  333.         switch (*s) {
  334.           case '0': case '1': case '2':
  335.           case '3': case '4': case '5':
  336.           case '6': ca